package edu.udo.sopra10.chaturaji.events;

import java.util.ArrayList;
import java.util.HashSet;

import edu.udo.sopra10.chaturaji.entities.Player;
import edu.udo.sopra10.chaturaji.entities.Turn;
import edu.udo.sopra10.chaturaji.entities.transfer.DiceRoll;
import edu.udo.sopra10.chaturaji.entities.transfer.Piece;
import edu.udo.sopra10.chaturaji.entities.transfer.DiceRoll.EquivalenceClass;

/**
 * Request event that is invoked when a move should be made.
 * 
 * @author Patrick Westerhoff
 */
public class MoveRequestEvent extends ChaturajiEvent
{
	private static final long serialVersionUID = -763108981400540843L;
	
	private int turnNumber;
	private byte playerId;
	private Player.Type playerType;
	private boolean firstMoveMade;
	private ArrayList<Byte> unassignedRolls;
	private HashSet<Piece> moveablePieces;
	
	/**
	 * Constructs a move request event based on the {@link Turn} entity.
	 * 
	 * @param source the source object.
	 * @param turn the turn entity this event is based on.
	 */
	public MoveRequestEvent ( Object source, Turn turn )
	{
		super( source );
		
		Player player = turn.getPlayer();
		
		// copy data from turn
		turnNumber = (int) Math.floor( player.getGame().getHistory().indexOf( turn ) / 4 );
		playerId = player.getTurnOrderPosition();
		playerType = player.getType();
		firstMoveMade = ( turn.getFirstMove() != null );
		unassignedRolls = new ArrayList<Byte>( turn.getUnassignedRolls() );
		
		// get roll types
		HashSet<DiceRoll.EquivalenceClass> rolls = new HashSet<EquivalenceClass>( 2 );
		for ( Byte roll : unassignedRolls )
		{
			rolls.add( DiceRoll.equivalenceClassFromRoll( roll ) );
		}
		
		// get moveable pieces
		moveablePieces = new HashSet<Piece>();
		
		for ( edu.udo.sopra10.chaturaji.entities.pieces.Piece piece : player.getPieces() )
		{
			if ( rolls.contains( DiceRoll.equivalenceClassFromPiece( piece ) ) )
				moveablePieces.add( Piece.createFromEntity( piece ) );
		}
	}
	
	/**
	 * Returns the current turn number.
	 * 
	 * @return the turn number.
	 */
	public int getTurnNumber ()
	{
		return turnNumber;
	}
	
	/**
	 * Returns the id of the current player.
	 * 
	 * @return the player id.
	 */
	public byte getPlayerId ()
	{
		return playerId;
	}
	
	/**
	 * Returns the type of the current player.
	 * 
	 * @return the player type.
	 */
	public Player.Type getPlayerType ()
	{
		return playerType;
	}
	
	/**
	 * Returns true if the first move of this turn was already made.
	 * 
	 * @return true if the first move was made.
	 */
	public boolean isFirstMoveMade ()
	{
		return firstMoveMade;
	}
	
	/**
	 * Returns a collection of all unassigned dice rolls.
	 * 
	 * @return the unassigned rolls.
	 */
	public ArrayList<Byte> getUnassignedRolls ()
	{
		return unassignedRolls;
	}
	
	/**
	 * Returns a set of all moveable pieces.
	 * 
	 * @return the moveable pieces.
	 */
	public HashSet<Piece> getMoveablePieces ()
	{
		return moveablePieces;
	}
}